package vip.zj.utils;

import it.sauronsoftware.jave.AudioAttributes;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncodingAttributes;
import it.sauronsoftware.jave.VideoAttributes;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by LYQ on 2017/11/2 0002.
 */
public class VideoUtils {

    /**
     * 视频转换
     * @param sourceUrl 源文件地址
     * @param targetUrl 转换的文件地址
     */
    public static void converts(String sourceUrl, String targetUrl) {
//        sourceUrl = "D:\\工程机械图片\\水平定向钻机\\桩工设备5.MOV";
//        targetUrl = "D:\\工程机械图片\\水平定向钻机\\桩工设备5.1.mp4";
        File source = new File(sourceUrl);
        File target = new File(targetUrl);
        try {

            AudioAttributes audio = new AudioAttributes();
            audio.setCodec("libmp3lame");
            audio.setBitRate(new Integer(56000000));
            audio.setChannels(new Integer(1));
            audio.setSamplingRate(new Integer(48000));
            VideoAttributes video = new VideoAttributes();
            video.setCodec("mpeg4");
            video.setBitRate(new Integer(8000000));
            video.setFrameRate(new Integer(50));
            EncodingAttributes attrs = new EncodingAttributes();
            attrs.setFormat("mp4");
            attrs.setAudioAttributes(audio);
            attrs.setVideoAttributes(video);
            Encoder encoder = new Encoder();
            encoder.encode(source, target, attrs);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取视频总时间
     *
     * @param video_path  视频路径
     * @param ffmpeg_path ffmpeg路径
     * @return
     */
    public static int getVideoTime(String ffmpeg_path, String video_path) {
        List<String> commands = new ArrayList<>();
        commands.add(ffmpeg_path);
        commands.add("-i");
        commands.add(video_path);
        try {
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commands);
            final Process p = builder.start();
            //从输入流中读取视频信息
            String results = IOUtils.toString(p.getErrorStream(), "utf-8");
            int value = p.waitFor();
            System.out.println(value);
            p.destroy();
            //从视频信息中解析时长
            String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
            Pattern pattern = Pattern.compile(regexDuration);
            Matcher m = pattern.matcher(results);
            if (m.find()) {
                int time = getTimelen(m.group(1));
                System.out.println(video_path + ",视频时长：" + time + ", 开始时间：" + m.group(2) + ",比特率：" + m.group(3) + "kb/s");
                return time;
            }


            commands.add("-acodec copy -vcodec copy -moveflags faststart");
            commands.add(video_path);
            ProcessBuilder builders = new ProcessBuilder();
            builders.command(commands);
            final Process process = builders.start();
            //从输入流中读取视频信息
            int values = process.waitFor();
            System.out.println(values);
            process.destroy();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    // 格式:"00:00:10.68"
    private static int getTimelen(String timelen) {
        int min = 0;
        String strs[] = timelen.split(":");
        if (strs[0].compareTo("0") > 0) {
            min += Integer.valueOf(strs[0]) * 60 * 60;//秒
        }
        if (strs[1].compareTo("0") > 0) {
            min += Integer.valueOf(strs[1]) * 60;
        }
        if (strs[2].compareTo("0") > 0) {
            min += Math.round(Float.valueOf(strs[2]));
        }
        return min;
    }

    /**
     * 从视频中获取图片
     *
     * @param ffmpeg_path ffmpeg路径
     * @param video_path 视频路径
     * @param number 获取图片数量（单位秒）
     * @param picLocation 图片位置
     * @param filePath 文件存放路径
     * @return
     */
    public static volatile int threadMun;

    public static void getPicFromVideo(String ffmpeg_path, String video_path, Integer number, String picLocation) throws Exception {
        int videoLength = getVideoTime(ffmpeg_path, video_path);
        if(Objects.isNull(number)){
            number = videoLength;
        }
        if (videoLength == 0) {
            throw new Exception("获取视频长度出错！");
        }
        int start = videoLength / 50;
        //以下是视频截取帧
        for (int i = 0; i < number; i=i+2) {
            int now = start + videoLength / number * i;
            long l = System.currentTimeMillis();
            String s = ffmpeg_path + " -i " + video_path + " -ss " + now + " -r 1 -t 1 -f image2 " + picLocation + File.separator + l + ".jpg";
//            String s = ffmpeg_path + " -i " + video_path + " -ss " + now + " -y -t 2.5 -vframes 65 -f image2 " + picLocation + File.separator + l + ".jpg";
            //linux下命令
            //Runtime.getRuntime().exec(s);
            // windows下命令
            String[] cmd = {"cmd", "/C", s};
            System.out.println(cmd[2]);
            Process process = Runtime.getRuntime().exec(cmd);
            try (
                    InputStream inputStream = process.getInputStream();
                    InputStream inputErrorStream = process.getErrorStream();
            ) {
                // 读取Shell的输出内容，并添加到string中：
                //启动两个线程，一个线程负责读标准输出流，另一个负责读标准错误流
                new Thread(() -> {
                    try {
                        String s1 = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).start();

                new Thread(() -> {
                    try {
                        String errMsg = IOUtils.toString(inputErrorStream, StandardCharsets.UTF_8);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).start();

                process.waitFor(2, TimeUnit.HOURS);////可能导致进程阻塞，甚至死锁
                int exitCode = process.exitValue();//
            }
            process.destroy();
        }
    }
    //以下是在线播放
    //完成后 进程必须销毁
//        int now = start + videoLength/number*5;
//        String cmd = ffmpeg_path + "-i" + video_path + "-ss" + now + "-r l -t l -f image2" + filePath;
//        Process process = Runtime.getRuntime().exec(cmd);
//        int value = process.waitFor();
//        process.destroy();

}
